package com.greensam.pixelengine.service.impl;

import com.greensam.pixelengine.constant.UserConstant;
import com.greensam.pixelengine.exception.BusinessException;
import com.greensam.pixelengine.pojo.emuns.ErrorCodeEnum;
import com.greensam.pixelengine.pojo.entity.*;
import com.greensam.pixelengine.repository.RoleRepository;
import com.greensam.pixelengine.repository.UserRoleRepository;
import com.greensam.pixelengine.service.RoleDataService;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author Macro_Ray
 * @since 2025/6/19 15:01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleDataServiceImpl implements RoleDataService {

    private final JPAQueryFactory jpaQueryFactory;
    private final RoleRepository roleRepository;
    private final UserRoleRepository userRoleRepository;

    @Override
    public void save(RolePo rolePo) {
        roleRepository.save(rolePo);
    }

    @Override
    public List<RolePo> listRolePo() {
        return roleRepository.findAllByDelete(Boolean.FALSE);
    }

    @Override
    public Optional<RolePo> getRolePoByCode(String code) {
        if (Objects.isNull(code)) {
            return Optional.empty();
        }
        QRolePo r = QRolePo.rolePo;
        return Optional.ofNullable(jpaQueryFactory.selectFrom(r)
                .where(r.code.eq(code)
                        .and(r.delete.eq(Boolean.FALSE)))
                .fetchOne());
    }

    @Override
    public Optional<RolePo> getRoleById(Long id) {
        return roleRepository.findByIdAndDelete(id, Boolean.FALSE);
    }

    @Override
    public List<UserRolePo> listUserRoleByRoleId(Long roleId) {
        return userRoleRepository.findAllByRoleIdAndDelete(roleId, Boolean.FALSE);
    }

    @Override
    public Boolean isAdmin(Long userId) {
        if (Objects.isNull(userId)) {
            return Boolean.FALSE;
        }
        RolePo rolePo = getRolePoByCode(UserConstant.ADMIN_ROLE_VALUE)
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.RoleNotExist));
        return listUserRoleByRoleId(rolePo.getId()).stream()
                .filter(Objects::nonNull)
                .anyMatch(userRole -> userRole.getUserId().equals(userId));
    }

    @Override
    public List<RolePermissionPo> listRolePermissionByRoleIds(List<Long> roleIds) {
        if (roleIds.isEmpty()) {
            return Collections.emptyList();
        }
        QRolePermissionPo rp = QRolePermissionPo.rolePermissionPo;
        return jpaQueryFactory.selectFrom(rp)
                .where(rp.roleId.in(roleIds)
                        .and(rp.delete.eq(Boolean.FALSE)))
                .fetch();
    }
}
